package service

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"choujiang/common/consts"
	"choujiang/common/db"
	"choujiang/common/models"
	"choujiang/common/utils"
	"strconv"
	"time"
)

const (
	SHARE_TOKEN_COLLECTION = "BoxCollection::sharetoken"     //mongodb分享token 集合名
	SHARE_TOKEN_KEY        = "BoxKey::leyouboxsharegroup_"   //redis分享群记录
	INVITE_FRIEND_KEY      = "BoxKey::leyouboxinvitefriend_" //redis邀请新玩家记录
	GAMEID                 = "leyoubox"
	FIRST_REWARD           = 10
	THIRD_REWARD           = 20
	INVITE_FRIEND_REWARD   = 30                                  //邀请3个好友奖励
	INVITE_EVERY_REWARD    = 100                                 //每邀请一个用户都得到奖励
	ADDITION_NUM_EVERY_DAY = "BoxKey::leyouboxadditioneveryday_" //每日新增团队人数redis key
	ADDITION_NUM_TOTAL     = "BoxKey::leyouboxaddtitontotal_"    //总团队成员人数redis key
)

type newShareInfo struct {
	GroupId string `json:"openGId"`
}

/**
 生成分享token
 */
func GetUserShareToken(user *model.User, goodsId int64) (string, error) {
	token := db.Mgo.GenToken(SHARE_TOKEN_COLLECTION, user.Id, goodsId)
	return token, nil
}

func GetJumpSdkToken(user *model.User, toGame, shareToken string) (string, error) {
	token := db.Mgo.GenSdkToken(user.Id, toGame, shareToken, user.HeadImgUrl, user.NickName)
	return token, nil
}

/**
 验证token的合法性
 */
func ValidateShareToken(shareToken string) (int, db.ShareToken) {
	shareStruct, reInt := db.Mgo.TokenExist(SHARE_TOKEN_COLLECTION, shareToken)
	return reInt, shareStruct
}

/*
 验证sdk token的合法性
 */
func ValidateSdkToken(token string) (int, db.SdkToken) {
	sdkStruct, reInt := db.Mgo.CheckSdkToken(token)
	return reInt, sdkStruct
}

/**
 领取分享到群的奖励
 */
func GetShareReward(iv, encryptedData string, shareStruct db.ShareToken, gameId, openId string) *utils.ErrorType {
	shareInfo, err := ParseShareInfo(openId, gameId, encryptedData, iv)
	if err != nil {
		fmt.Printf("ParseShareInfo err : %+v\n", err)
		return consts.ErrInterval
	}
	shareKey := SHARE_TOKEN_KEY + strconv.FormatInt(shareStruct.UserId, 10)
	keyExist := db.MainRedisClient.Exists(shareKey)
	if keyExist.Val() == 0 { //没有分享过
		var sliceShare []string
		newSlice := append(sliceShare, shareInfo.GroupId)
		jsonSlice, _ := json.Marshal(newSlice)
		db.MainRedisClient.HSet(shareKey, utils.TodayUnix(), jsonSlice)
		//完成分享一次到群领取金币任务
		completeTask(shareStruct.UserId, FIRST_REWARD)
		//记录任务
		db.Mgo.CompleteTask(shareStruct.UserId, db.SHARE_GROUP_TASK, true)
		//记录金币来源
	} else { //有分享记录
		toDayExist := db.MainRedisClient.HExists(shareKey, utils.TodayUnix())
		if toDayExist.Val() { //今天分享过
			var jsonSlice []string
			stringVal := db.MainRedisClient.HGet(shareKey, utils.TodayUnix())
			json.Unmarshal([]byte(stringVal.Val()), &jsonSlice)
			if utils.StringInSlice(jsonSlice, shareInfo.GroupId) {
				return consts.ErrShareSameGroup
			} else {
				switch len(jsonSlice) {
				case 1: //分享1次
					newSlice := append(jsonSlice, shareInfo.GroupId)
					newJsonSlice, _ := json.Marshal(newSlice)
					db.MainRedisClient.HSet(shareKey, utils.TodayUnix(), newJsonSlice)
					//记录任务
					db.Mgo.CompleteTask(shareStruct.UserId, db.SHARE_THREE_GROUP_TASK, false)
				case 2: //分享2次
					newSlice := append(jsonSlice, shareInfo.GroupId)
					newJsonSlice, _ := json.Marshal(newSlice)
					db.MainRedisClient.HSet(shareKey, utils.TodayUnix(), newJsonSlice)
					//完成分享三次到群领取金币任务
					completeTask(shareStruct.UserId, THIRD_REWARD)
					//记录任务
					db.Mgo.CompleteTask(shareStruct.UserId, db.SHARE_THREE_GROUP_TASK, true)
					//记录金币来源
				default:
					return consts.ErrShareTaskAlreadyDone
				}
			}
		} else { //今天还没分享过
			var sliceShare []string
			newSlice := append(sliceShare, shareInfo.GroupId)
			jsonSlice, _ := json.Marshal(newSlice)
			db.MainRedisClient.HSet(shareKey, utils.TodayUnix(), jsonSlice)
			//完成分享一次到群领取金币任务
			completeTask(shareStruct.UserId, FIRST_REWARD)
			//记录任务
			db.Mgo.CompleteTask(shareStruct.UserId, db.SHARE_GROUP_TASK, true)
			//记录金币来源
		}
	}
	return nil
}

func ParseShareInfo(minigameOpenId string, gameId string, encryptedData, iv string) (shareInfo *newShareInfo, err error) {
	sessionKey, err := GetUserSessionKey(minigameOpenId, gameId)
	fmt.Printf("sessionKey: %s", sessionKey)
	if err != nil {
		return
	}
	key, err := base64.StdEncoding.DecodeString(sessionKey)
	if err != nil {
		return
	}
	data, err := base64.StdEncoding.DecodeString(encryptedData)
	if err != nil {
		fmt.Println(err)
		return
	}
	ivb, err := base64.StdEncoding.DecodeString(iv)
	if err != nil {
		return
	}
	origData, err := utils.AesPkcs7Decrypt(data, key, ivb)
	if err != nil {
		return
	}
	shareInfo = &newShareInfo{}
	err = json.Unmarshal(origData, shareInfo)
	if err != nil {
		return
	}
	return
}

func completeTask(userId int64, point int64) {
	_, err := db.MysqlEngine.Exec("update user_extra set point = point + ? where user_id = ?", point, userId)
	if err != nil {
		fmt.Printf("Add user point err:", err)
	}
	commonKey := "BoxKey::leyouboxtaskaccumkey_" + strconv.FormatInt(userId, 10)
	keyExist := db.MainRedisClient.Exists(commonKey)
	if keyExist.Val() == 1 {
		reVal := db.MainRedisClient.Get(commonKey)
		intCoins, _ := strconv.ParseInt(reVal.Val(), 10, 64)
		db.MainRedisClient.Set(commonKey, point+intCoins, time.Hour*24)
	} else {
		db.MainRedisClient.Set(commonKey, point, time.Hour*24)
	}
}

/**
 发展新用户领取奖励
 */
func ShareUserReward(userId int64, parentId int64, gameId string) {
	if gameId != "" && gameId != "leyoubox" { //新盒子
		inviteKey := INVITE_FRIEND_KEY + gameId + strconv.FormatInt(parentId, 10)
		keyExist := db.MainRedisClient.Exists(inviteKey)
		if keyExist.Val() == 0 { //没有邀请过玩家
			db.MainRedisClient.SAdd(inviteKey, userId)
			//记录任务完成信息
			db.Mgo.CompleteNewTask(parentId, db.NEW_INVITE_FRIEND_TASK, false)
		} else { //邀请过玩家
			keyExist := db.MainRedisClient.SIsMember(inviteKey, userId)
			if !keyExist.Val() { //没有邀请过这个玩家
				keyNum := db.MainRedisClient.SCard(inviteKey)
				if keyNum.Val() == 2 { //任务完成
					if db.Mgo.TakeRedPack(parentId, 2) { //完成了两个任务，领取3元红包
						_, err := db.MysqlEngine.Exec("update user_extra set balance = balance + ? where user_id = ?", 3, parentId)
						if err != nil {
							fmt.Printf(" err is %s", err)
						}
					}
					//记录任务完成信息
					db.Mgo.CompleteNewTask(parentId, db.NEW_INVITE_FRIEND_TASK, true)
				} else {
					db.Mgo.CompleteNewTask(parentId, db.NEW_INVITE_FRIEND_TASK, false)
				}
				db.MainRedisClient.SAdd(inviteKey, userId)
			}
		}
	} else { //第一版盒子
		inviteKey := INVITE_FRIEND_KEY + strconv.FormatInt(parentId, 10)
		keyExist := db.MainRedisClient.Exists(inviteKey)
		if keyExist.Val() == 0 { //没有邀请过玩家
			var inviteSlice []int64
			newSlice := append(inviteSlice, userId)
			jsonSlice, _ := json.Marshal(newSlice)
			db.MainRedisClient.HSet(inviteKey, utils.TodayUnix(), jsonSlice)
			//记录任务完成信息
			db.Mgo.CompleteTask(parentId, db.INVITE_FRIEND_TASK, false)
		} else { //邀请过玩家
			toDayExist := db.MainRedisClient.HExists(inviteKey, utils.TodayUnix())
			if toDayExist.Val() { //今天邀请过玩家
				var jsonSlice []int64
				stringVal := db.MainRedisClient.HGet(inviteKey, utils.TodayUnix())
				json.Unmarshal([]byte(stringVal.Val()), &jsonSlice)
				db.Mgo.CompleteTask(parentId, db.INVITE_FRIEND_TASK, false)
				//记录邀请信息
				newSlice := append(jsonSlice, userId)
				newJsonSlice, _ := json.Marshal(newSlice)
				db.MainRedisClient.HSet(inviteKey, utils.TodayUnix(), newJsonSlice)
			} else { //今天没邀请过玩家
				//记录邀请信息
				var inviteSlice []int64
				newSlice := append(inviteSlice, userId)
				jsonSlice, _ := json.Marshal(newSlice)
				db.MainRedisClient.HSet(inviteKey, utils.TodayUnix(), jsonSlice)
				//记录任务完成信息
				db.Mgo.CompleteTask(parentId, db.INVITE_FRIEND_TASK, false)
			}
		}
	}
	//每发展一个新用户都得到金币奖励
	completeTask(parentId, INVITE_EVERY_REWARD)
	//记录每日新增和总成员数
	recordNewAdditions(parentId)
	//记录金币来源
}

/**
 记录每日新增和总成员数
 */
func recordNewAdditions(userId int64) {
	//每日新增加一
	todayAddtionKey := ADDITION_NUM_EVERY_DAY + strconv.FormatInt(userId, 10) + "_" + utils.TodayUnix()
	keyExist := db.MainRedisClient.Exists(todayAddtionKey)
	if keyExist.Val() == 1 {
		db.MainRedisClient.Incr(todayAddtionKey)
	} else {
		db.MainRedisClient.Set(todayAddtionKey, 1, time.Hour*24)
	}
	//总人数加一
	totalAddtionKey := ADDITION_NUM_TOTAL + strconv.FormatInt(userId, 10)
	totalKeyExist := db.MainRedisClient.Exists(totalAddtionKey)
	if totalKeyExist.Val() != 1 { //key不存在
		userCount, _ := db.MysqlEngine.SQL("select count(*) from user_extra where parent_id = ?", userId).Count()
		db.MainRedisClient.Set(totalAddtionKey, userCount, 0)
	} else {
		db.MainRedisClient.Incr(totalAddtionKey) //redis总人数加一
	}
}

/**
 获取分享页面内容
 */
func GetSharePage() (model.SharePage, error) {
	sharePage := model.SharePage{}
	_, err := db.MysqlEngine.Get(&sharePage)
	if err != nil {
		fmt.Printf("GetRecommendList err:%+v\n", err)
	}
	sharePage.PathUrl = utils.AddPrefix(sharePage.PathUrl)
	return sharePage, err
}
